﻿#region Copyright (c) 07/18/2012, Olaf Kober <amarok.projects@gmail.com>
//================================================================================
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.
//================================================================================
#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;


namespace Amarok.Presentation
{
	/// <summary>
	/// Converts the given Int32 to the Object at the index position in the set Values collection.
	/// 
	/// :: Convert
	/// 0..n          ...  Object at the Index position
	/// Out-Of-Range  ...  DefaultValue
	/// 
	/// :: ConvertBack
	/// equal to Object at Index position   ...  Index
	/// not equal to any Object             ...  DependencyProperty.Unset
	/// </summary>
	[ContentProperty("Values")]
	[ValueConversion(typeof(Int32), typeof(Object))]
	public sealed class IndexToObjectConverter : ValueConverter<Int32, Object>
	{
		/// <summary>
		/// Gets or sets a collection of Objects. The Convert() method uses this collection to return the Object 
		/// at the index that is represented by the supplied Int32 value. Defaults to an empty list.
		/// </summary>
		public List<Object> Values
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the Object that is returned by the Convert() method when the supplied Int32 value 
		/// is outside of the list collection bounds. Defaults to DependencyProperty.UnsetValue.
		/// </summary>
		public Object DefaultValue
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the Object that is returned by the ConvertBack() method when the supplied Object is not 
		/// equal to any of the Objects stored in the Values collection. Defaults to DependencyProperty.UnsetValue.
		/// </summary>
		public Object DefaultIndex
		{
			get;
			set;
		}


		/// <summary>
		/// Initializes a new instance.
		/// </summary>
		public IndexToObjectConverter()
		{
			this.Values = new List<Object>();
			this.DefaultValue = DependencyProperty.UnsetValue;
			this.DefaultIndex = DependencyProperty.UnsetValue;
		}


		/// <summary>
		/// </summary>
		protected override Object OnConvert(Int32 value, Type targetType, Object parameter, CultureInfo culture)
		{
			if (this.Values == null)
				return this.DefaultValue;
			if (value < 0 || value >= this.Values.Count)
				return this.DefaultValue;

			return this.Values[value];
		}

		/// <summary>
		/// </summary>
		protected override Object OnConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture)
		{
			if (this.Values == null)
				return this.DefaultIndex;

			for (Int32 i = 0; i < this.Values.Count; i++)
			{
				if (Object.Equals(this.Values[i], value))
					return i;
			}

			return this.DefaultIndex;
		}

	}
}
